package collections;

import util.Tracer;

public class Queue <T>{
	private Object[] items;
	private int head;
	private int tail;
	public Queue(int capacity) {
		items = new Object[capacity + 1];
		head = 0;
		tail = 0;
	}
	
	public void enqueue(T t) throws Exception
	{
		int nextTail = (tail + 1) % items.length;
		if(nextTail == head)
		{
			throw new Exception("overflow");
		}
		
		items[tail] = t;
		
		tail = nextTail;
	}
	
	public boolean isEmpty()
	{
		return head == tail;
	}
	
	@SuppressWarnings("unchecked")
	public T dequeue() throws Exception
	{
		if(head == tail)
			throw new Exception("underflow");
		
		T t = (T)items[head];
		head = (head + 1) % items.length;
		return t;
	}
	
	public static void main(String[] args) throws Exception {
		Queue<Integer> q = new Queue<Integer>(5);
		q.enqueue(1);
		q.enqueue(2);
		q.enqueue(3);
		Tracer.trace(q.dequeue());
		q.enqueue(4);
		Tracer.trace(q.dequeue());
		q.enqueue(5);
		Tracer.trace(q.dequeue());
		q.enqueue(6);
		Tracer.trace(q.dequeue());
		Tracer.trace(q.dequeue());
		Tracer.trace(q.dequeue());
		Tracer.trace(q.dequeue());
	}
}
